package main

import (
	"fmt"
	"reflect"
)

type User struct {
	ID   int
	Name string
	Age  int
}

func (u User) ReflectCallFunc() int {
	fmt.Println("caixisheng ReflectCallFunc")
	return 1
}
func main() {
	user := User{1, "Caixisheng", 25}
	DoFileAndMethod(user)
}

func DoFileAndMethod(input interface{}) {
	getType := reflect.TypeOf(input)
	fmt.Println("get Type is :", getType.Name())

	getValue := reflect.ValueOf(input)
	fmt.Println("get all Value is: ", getValue)

	// 获取字段方法
	// 1.先获取interface的reflect.Type, 然后通过NumField进行遍历
	// 2.再通过reflect.Type的Field获取其Field
	// 3.最后通过Field的interface()得到value
	for i := 0; i < getValue.NumField(); i++ {
		field := getType.Field(i)
		value := getValue.Field(i)
		fmt.Printf("%s: %v = %v\n", field.Name, field.Type, value)
	}

	// 获取方法
	// 1.先获取interface的reflect.Type, 然后通过.NumMethod进行遍历
	for i := 0; i < getType.NumMethod(); i++ {
		m := getType.Method(i)
		fmt.Printf("%s: %v\n", m.Name, m.Type)
	}
}

// instruction
// 通过运行结果可以得知获取未知类型的interface的具体变量及步骤
// 再通过reflect.Type的Field获取其Field
// 最后通过Field的Interface()获得对应的Value

// 通过运行结构可以得知获取未知类型的interface的所属方法(函数)的步骤为：
//
